package io.gitee.geminidev.bot;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import io.gitee.geminidev.bot.api.MessageApi;
import io.gitee.geminidev.bot.api.MessageHttpApiFactory;
import io.gitee.geminidev.bot.domain.ChannelMessage;
import io.gitee.geminidev.bot.domain.GuildMessage;
import io.gitee.geminidev.bot.domain.Message;
import io.gitee.geminidev.bot.domain.ReadyMessage;
import io.gitee.geminidev.bot.type.EventType;
import io.gitee.geminidev.bot.type.IntentType;
import io.gitee.geminidev.bot.websocket.BotWebSocket;
import io.gitee.geminidev.bot.websocket.BotWebSocketClient;
import io.gitee.geminidev.bot.event.Callback;

import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author gemini
 * @Date 2023/4/2 22:43
 * @description:
 */
public class Bot {

    public static MessageApi messageApi(){
        return MessageHttpApiFactory.INSTANCE.getInstance();
    }
    public static String at(String authorId){
        if(StrUtil.isEmpty(authorId)){
            return "";
        }
        return String.format("\u003c@!%s\u003e", authorId);
    }

    public static String emoji(int code){
        return String.format("\u003cemoji:%s\u003e", code);
    }

    public static String getApplicationDirectory(){
        return System.getProperty("user.dir");
    }

    public static File getApplicatioinDataDirectory(){
        File file = FileUtil.file(getApplicationDirectory() + File.separator + "data");
        if(!file.exists()){
            file.mkdirs();
        }
        return file;
    }

    public static File getApplicationiTempDirectory(){
        File file = FileUtil.file(getApplicatioinDataDirectory(), "temp/" + DateUtil.formatDate(new Date()));
        if(!file.exists()){
            file.mkdirs();
        }
        return file;
    }

    public static List<String> getMatcherGroups(String content, String regex){
        String text = content;
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(text);
        List<String> result = new ArrayList<>();
        while (matcher.find()) {
            for (int i = 0; i < matcher.groupCount() + 1; i++) {
                result.add(matcher.group(i));
            }
        }
        return result;
    }

    /** websocket */
    private BotWebSocket webSocket;

    /** context */
    private BotContext context;


    /**
     * 订阅频道消息
     * @param event
     * @return
     */
    public Bot onGuildCreate(Callback<GuildMessage> event){
        webSocket.on(EventType.GUILD_CREATE, event);
        return this;
    }

    public Bot onMessageCreate(Callback<Message> event){
        webSocket.on(EventType.MESSAGE_CREATE, event);
        return this;
    }

    public Bot onAtMessageCreate(Callback<Message> event) {
        webSocket.on(EventType.AT_MESSAGE_CREATE, event);
        return this;
    }

    /**
     * 订阅就绪事件
     * @param event
     * @return
     */
    public Bot onReady(Callback<ReadyMessage> event){
        webSocket.on(EventType.READY, event);
        return this;
    }

    /**
     * 订阅频道消息
     * @param event
     * @return
     */
    public Bot onChannelCreate(Callback<ChannelMessage> event){
        webSocket.on(EventType.CHANNEL_CREATE, event);
        return this;
    }

    public Bot start(){
        webSocket.start();
        return this;
    }

    public Bot intents(IntentType...intents){
        int result = 0;
        for (IntentType intent : intents) {
            result = result | intent.intent();
        }
        this.webSocket.setIntents(result);
        return this;
    }

    protected void setWebSocket(BotWebSocket webSocket) {
        this.webSocket = webSocket;
    }

    public BotWebSocket getWebSocket() {
        return webSocket;
    }

    public BotContext getContext() {
        return context;
    }

    public void init(String botAppId, String botToken, boolean sandbox) {
        // init context
        context = BotContextFactory.INSTANCE.getInstance();
        context.setBotAppId(botAppId);
        context.setBotToken(botToken);
        context.setSandbox(sandbox);

        // init websocket
        URI uri = null;
        try {
            uri = new URI(context.getWssUri());
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        webSocket = new BotWebSocketClient(uri, context.getToken());
        webSocket.setIntents(0
                | IntentType.GUILDS.intent()
                | IntentType.GUILD_MEMBERS.intent()
                | IntentType.GUILD_MESSAGE_REACTIONS.intent()
                | IntentType.OPEN_FORUMS_EVENT.intent()
                | IntentType.AUDIO_OR_LIVE_CHANNEL_MEMBER.intent()
                | IntentType.INTERACTION.intent()
                | IntentType.AUDIO_ACTION.intent()
                | IntentType.PUBLIC_GUILD_MESSAGES.intent());

        // create api
        MessageHttpApiFactory.INSTANCE.createApi(context);
    }


}
